<?php
// 应用公共文件
use think\facade\Request;
use util\Assets;

/**
 * 将驼峰字符串转为下划线加小写的形式
 * @param string $str
 * @return string
 * Author: LCY<409028735@qq.com>
 * Time: 2020/12/2 22:01
 * Note:
 */
function parse_camel_to_lower($str = '')
{
    $str = preg_replace('/([A-Z])/', '_\\1', $str);
    return trim(strtolower($str), '_');
}

/**
 * 获取浏览器类型
 * @return string
 * Author: LCY<409028735@qq.com>
 * Time: 2021/11/15 12:37
 * Note:
 */
function get_browser_type()
{
    $agent = !empty($_SERVER["HTTP_USER_AGENT"]) ? $_SERVER["HTTP_USER_AGENT"] : '';
    if (empty($agent)) {
        return 'unknown';
    }
    if (strpos($agent, 'MSIE') !== false || strpos($agent, 'rv:11.0')) return "ie";
    if (strpos($agent, 'Firefox') !== false) return "firefox";
    if (strpos($agent, 'Chrome') !== false) return "chrome";
    if (strpos($agent, 'Opera') !== false) return 'opera';
    if ((strpos($agent, 'Chrome') == false) && strpos($agent, 'Safari') !== false) return 'safari';
    if (false !== strpos($_SERVER['HTTP_USER_AGENT'], '360SE')) return '360SE';
    return 'unknown';
}

/**
 * 封装ajax响应的结果
 * @param int $code  状态码
 * @param string $msg  提示信息
 * @param array|null $data   返回数据
 * @param int $wait    跳转等待时间秒数
 * @param string $url  跳转链接地址
 * @return \think\response\Json|\think\response\View
 * Author: LCY<409028735@qq.com>
 * Time: 2021/11/14 23:23
 * Note:
 */
function ajax_return($code, $msg = '', $url = null, $data = '', $wait = 3)
{
    $result = [
        'code' => $code,
        'msg' => $msg,
        'data' => $data,
        'wait' => $wait,
        'url'  => $url,
        'token' => Request::token(),
    ];
    return json($result);
}

/**
 * 将数据按指定的类型返回（array、string）
 * @param $data  array|string
 * @param $type string  类型（array|string）
 * @return mixed  返回数组或带逗号分隔的字符串
 * Author: LCY<409028735@qq.com>
 * Time: 2021/11/18 13:18
 * Note:数组和包含逗号的字符串之间的数据转换
 */
function data_to_type($data, $type = 'array')
{
    if (!in_array($type, ['string', 'array'])) {
        throw new \Exception('类型参数有误，只支持string或array');
    }
    switch (gettype($data)) {
        case 'string':
            if ($type == 'array') {
                $data = explode(',', $data);
            }
            break;
        case 'array':
            if ($type == 'string') {
                $data = implode(',', $data);
            }
            break;
        default:
            if ($type == 'array') {
                $data = (array)$data;
            } else {
                $data = (string)$data;
            }
    }

    return $data;
}

/**
 * 加密登录密码
 * @param $password
 * @param string $salt
 * @return string
 * Author: LCY<409028735@qq.com>
 * Time: 2021/11/19 14:40
 * Note:
 */
function encrypt_password($password, $salt = 'myadmin')
{
    return md5(sha1($salt . sha1($password . $salt) . $salt) . $salt);
}

/**
 * 获取系统默认图片
 * @param string $type
 * @return mixed|string
 * Author: LCY<409028735@qq.com>
 * Time: 2021/4/23 10:32
 * Note:
 */
function get_default_img($type = '')
{
    //文件保存的根目录
    $root_path = '/static/default/img/';

    $imgs = [
        'admin-avatar' => $root_path . 'admin-avatar.png',
        'user-avatar' => $root_path . 'user-avatar.png',
        'home-cover' => $root_path . 'home-cover.jpg',
        'favicon' => $root_path . 'favicon.png',
    ];

    if (key_exists($type, $imgs)) {
        return $imgs[$type];
    }
    return '';
}


/**
 * 删除指定的文件夹的全部文件
 *
 * @param string $dir 指定的文件夹路径
 * @param boolean $withSelf 是否删除指定的文件夹自己
 * @return bool
 */
function remove_directory($dir = '', $withSelf = false)
{
    if (empty($dir) || !is_dir($dir)) {
        return true;
    }
    $files = scandir($dir);
    foreach ($files as $file) {
        if ('.' != $file && '..' != $file) {
            $path = $dir . DIRECTORY_SEPARATOR . $file;
            if (is_dir($path)) {
                remove_directory($path);
                @rmdir($path);
            } else {
                @unlink($path);
            }
        }
    }

    if ($withSelf) {
        @rmdir($dir);
    }

    return true;
}

/**
 * 动态加载静态资源
 *
 * @param array|string $names 静态资源名称列表[名称可参考：/extend/util/Assets.php中的assets属性定义]
 * @param string $type 加载的类型 css或js
 * @return string 多个静态资源的字符串列表
 */
function load_assets($names, $type = 'css')
{
    return Assets::loadAssets($names, $type);
}

/**
 * 加载每个控制器的自定义的资源文件
 * @param string|array $names  资源列表，默认自动获取当前的控制器的名称[名称可参考：/public/static/{$modele}/js/{$controller}/下的文件定义]
 * @param string $type 类型 css或js，默认js
 * @param string $module 所属的模块，默认自动获取当前的模块名称
 * @param string $controller 所属的控制器，默认自动获取当前的控制器名称
 * @return string
 */
function load_module_assets($names = '', $type = 'js', $module = '', $controller = '')
{
    //确定要加载的类库名称
    $names = !empty($names) ? $names : 'index';
    if (!is_array($names)) {
        $names = explode(',', $names);
    }
    //确定要加载模块
    $module = !empty($module) ? $module : request()->module();

    //确定加载的控制器-对应public/static/{$module}/js/下的子目录
    $controller = !empty($controller) ? $controller : parse_camel_to_lower(request()->controller());

    return Assets::loadModuleAssets($names, $type, $module, $controller);
}

/**
 * 格式化输出json（主要是换行和缩进，便于在网页中展示）
 *
 * @param string $str
 * @return false|string
 */
function format_json($str = '')
{
    is_string($str) && $str = json_decode($str);
    return json_encode($str, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
}

/**
 * 返回系统配置项
 * @param null|string|array $key  需要获取的键名，不填则获取全部，也可以获取部分（传入数据或逗号分隔的字符串）
 * @param string   $default   默认值
 * @param string   $filter   过滤器，多个用英文逗号分隔，适用于获取单条数据的时候有用
 * @return array|mixed|PDOStatement|string|\think\Model|null
 * @throws \think\db\exception\DataNotFoundException
 * @throws \think\db\exception\ModelNotFoundException
 * @throws \think\exception\DbException
 * Author: LCY<409028735@qq.com>
 * Time: 2020/12/2 16:40
 * Note:
 */
function get_system_config($key = null, $default = '', $filter = '')
{
    //获取缓存中的配置
    $configs = cache('configs');
    if (empty($configs)) {
        $configs = db('configs')->where('id', 1)->find();
        cache('configs', $configs);
    }

    //返回全部配置项
    if (is_null($key)) {
        return $configs;
    }

    //返回部分多条配置项
    if (is_string($key) && strpos($key, ',')) {
        $key = explode(',', $key);
    }

    if (is_array($key)) {
        $values = [];
        foreach ($key as $v) {
            if (array_key_exists($v, $configs)) {
                $values[$v] = $configs[$v];
            }
        }

        return $values;
    }

    //不能存在或空字符串则返回默认值
    if (!array_key_exists($key, $configs) || $configs[$key] == '') {
        return $default;
    }

    //返回单条配置项

    if (!empty($filter)) {
        //使用过滤器
        if (is_string($filter)) {
            $filter = explode(',', $filter);
        }
        $value = $configs[$key];
        foreach ($filter as $fl) {
            if (!empty($fl) && function_exists($fl)) {
                $value = $fl($value);
            }
        }

        return $value;
    }

    //不使用过滤器
    return  $configs[$key];
}


/**
 * 生成文件上传的模板，简化在页面中的代码编写
 * @param string $field 字段名称
 * @param string $files 默认的文件
 * @param string $require 是否必传
 * @param integer $width 建议图片宽度
 * @param integer $height 建议图片高度
 * @param integer $crop   裁剪方式
 * @param int $max_num  最多上传的文件数量
 * @param int $max_size 上传的单个文件的大小限制，单位MB
 * @param string $type  类型   image或file
 * @return string 直接可用于页面展示的上传组件
 */
function build_upload_template($field, $files = '', $require = 'off',$width = 500, $height = 500, $crop = 0, $max_num = 1, $max_size = 2, $type = 'image')
{
    $files = is_string($files) && !empty($files) ? explode(',', $files) : (array)$files;
    if ($max_num > 1 || count($files) > 1) {
        $multiple = true;
    } else {
        $multiple = false;
    }
    $title = $multiple ? '多' : '单';
    $name = $multiple ? $field . '[]' : $field;
    //过滤空的文件名
    $files = array_filter($files, function ($file) {
        if (empty($file)) {
            return false;
        }
        return true;
    });

    if ($type == 'image') {
        $title .= '图';
        $templates = '<div class="files" id="' . $field . '">
                       <span class="btn btn-sm btn-primary btn-upload-image" data-multiple="' . ($multiple ? 'true' : 'false') . '" data-max-num="' . $max_num . '" data-max-size="' . $max_size . '" data-width="' . $width . '" data-height="' . $height . '" data-crop="' . $crop . '"><i class="' . ($multiple ? 'fas fa-images' : 'fas fa-image') . '"></i>' . $title . '上传</span>
                                <div class="files-preview mt-2 d-flex flex-wrap ' . ($multiple ? 'draggable-zone' : '') . '" data-require="'.$require.'">';
        if (!empty($files)) {
            foreach ($files as $file) {
                if (empty($file)) {
                    continue;
                }
                $templates .= '<div class="card overlay w-125px h-125px me-3 mb-3 overflow-hidden shadow-sm  ' . ($multiple ? 'draggable' : '') . '">
                                        <div class="card-body p-0">
                                            <input type="hidden" name="' . $field . ($multiple ? '[]' : '') . '" value="' . $file . '">
                                            <div class="overlay-wrapper">
                                                <img src="' . $file . '" alt="" class="w-100"/>
                                            </div>
                                            <div class="overlay-layer bg-dark bg-opacity-25">
                                                <a href="' . $file . '" class="btn btn-primary btn-icon  btn-sm  img-link w-25px h-25px" title="查看大图"><i class="bi bi-eye"></i></a>
                                                <span class="btn btn-danger btn-icon  btn-sm ms-2 img-remove w-25px h-25px" data-field="' . $name . '" title="删除"><i class="bi bi-trash"></i></span>
                                                ' . ($multiple ? '<span class="btn btn-info btn-icon btn-sm ms-2 draggable-handle w-25px h-25px" title="拖拽排序"><i class="bi bi-arrows-move"></i></span>' : '') . '
                                            </div>
                                        </div>
                                    </div>';
            }
        } else {
            $templates .= '<input type="hidden" name="' . $name . '" value="" class="default-value" '.($require == 'on' ? 'data-rule="required"' : '').'/>';
        }


        return $templates . '</div></div>';
    } elseif ($type == 'file') {
        $title .= '文件';
        $templates = '<div class="files" id="' . $field . '">
                       <span class="btn btn-sm btn-primary btn-upload-file" data-multiple="' . ($multiple ? 'true' : 'false') . '" data-max-num="' . $max_num . '" data-max-size="' . $max_size . '" data-width="' . $width . '" data-height="' . $height . '" data-crop="' . $crop . '"><i class="fas fa-image"></i>' . $title . '上传</span>
                                <div class="files-preview mt-2 d-flex flex-wrap ' . ($multiple ? 'draggable-zone' : '') . '">';
        if (!empty($files)) {
            foreach ($files as $file) {
                if (empty($file)) {
                    continue;
                }
                $templates .= '<div class="card overlay w-125px h-125px me-3 mb-3 overflow-hidden bg-lighten  ' . ($multiple ? 'draggable' : '') . '">
                                        <div class="card-body p-0">
                                            <input type="hidden" name="' . $field . ($multiple ? '[]' : '') . '" value="' . $file . '">
                                            <div class="overlay-wrapper">
                                                <span class="text-muted">' . $file . '</span>
                                            </div>
                                            <div class="overlay-layer bg-dark bg-opacity-25">
                                                <a href="' . $file . '" download="" class="btn btn-primary btn-icon  btn-sm w-25px h-25px" title="下载文件"><i class="bi bi-download"></i></a>
                                                <span class="btn btn-danger btn-icon  btn-sm ms-2 img-remove w-25px h-25px" data-field="' . $name . '" title="删除"><i class="bi bi-trash"></i></span>
                                                ' . ($multiple ? '<span class="btn btn-info btn-icon btn-sm ms-2 draggable-handle w-25px h-25px" title="拖拽排序"><i class="bi bi-arrows-move"></i></span>' : '') . '
                                            </div>
                                        </div>
                                    </div>';
            }
        } else {
            $templates .= '<input type="hidden" name="' . $name . '" value="" class="default-value" />';
        }


        return $templates . '</div></div>';
    }

    return '';
}


/**
 * 过滤富文本中的内容
 * @param string $dirty_html
 * @return string
 * Author: LCY<409028735@qq.com>
 * Time: 2021/12/23 16:18
 * Note:
 */
function html_clean($dirty_html = '')
{
    if (empty($dirty_html)) {
        return '';
    }
    $config = HTMLPurifier_Config::createDefault();
    $purifier = new HTMLPurifier($config);
    return $purifier->purify($dirty_html);
}


/**
 * 记录详细的异常数据
 *
 * @param \Exception $e
 * @return void
 */
function recordExceptionInfo(\Exception $e)
{
    $error_info = [
        'msg' => $e->getMessage(),
        'file' => $e->getFile(),
        'code' => $e->getCode(),
        'line' => $e->getLine(),
        'trace' => $e->getTraceAsString(),
    ];
    trace($error_info, 'error');
}

/**
 * 生成订单号
 *
 * @return string
 */
function create_order_sn()
{
    return date('YmdHis') . mt_rand(0, 9) . mt_rand(0, 9) . mt_rand(0, 9) . mt_rand(0, 9) . mt_rand(0, 9);
}

/**
 * 生成指定日期区间的所有的日期
 * @param $start_date string  开始日期
 * @param $end_date   string  结束日期
 * @return array
 * Author: LCY<409028735@qq.com>
 * Time: 2021/1/12 12:27
 * Note:
 */
function build_date_range_array($start_date, $end_date)
{
    $start_date_timestamp = strtotime($start_date);
    $date_range_array = [];
    $i = 0;
    do {
        $start_date_temp = strtotime('+ ' . $i . ' days', $start_date_timestamp);
        $end_date_temp = date('Y-m-d', $start_date_temp);
        $date_range_array[] = $end_date_temp;
        $i++;
    } while ($end_date_temp < $end_date);

    return $date_range_array;
}


/**
 * 把分钟数格式化输出XX小时XX分钟的格式
 *
 * @param integer $minutes 分钟数
 * @return string
 */
function format_minutes($minutes = 0)
{
    if (empty($minutes)) {
        return '-';
    }
    $show_text = '';
    $hours = '';

    if ($minutes >= 60) {
        $hours = floor($minutes / 60);
        if ($hours) {
            $show_text .= $hours . '小时';
        }
        $minute = $minutes % 60;
        if ($minute) {
            $show_text .= $minute . '分钟';
        }
    } else {
        $show_text .= $minutes . '分钟';
    }


    return $show_text;
}
